﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading;

namespace DCT.Model
{
    public class DataAccess
    {
        #region Constructor

        private DataAccess()
        {
            _deviceModels = new List<DeviceBaseModel>();
            _deviceGraphModels = new List<DeviceBaseGraphModel>();

            CurrentSQLFileName = System.Windows.Forms.Application.StartupPath + Resource.DataAccesss_DefaultProjectFileName;
            File.Delete(CurrentSQLFileName);
            _dataContext = new SQLModelDataContext(CurrentSQLFileName);
            _dataContext.CreateDatabase();
        }

        #endregion

        #region Singleton

        private static DataAccess _instance;
        public static DataAccess Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new DataAccess();
                }
                return _instance;
            }
        }

        #endregion

        #region Fields

        SQLModelDataContext _dataContext;
        List<DeviceBaseModel> _deviceModels;
        List<DeviceBaseGraphModel> _deviceGraphModels;

        #endregion

        #region Properties

        public string CurrentXMLFileName { get; set; }
        public string CurrentSQLFileName { get; set; }

        #endregion

        #region Events

        public event EventHandler<DeviceModelEventArgs> DeviceModelRemoveHandler;

        #endregion

        #region Methods

        public bool LoadProjectFromXML(string projectFile)
        {
            if (XMLModel.LoadProject(projectFile, _deviceModels, _deviceGraphModels))
            {
                //Thread sqlSaveThread = new Thread(() => SQLModel.SaveProject(_dataContext, _deviceModels, _deviceGraphModels));
                //sqlSaveThread.Start();
                this.CurrentXMLFileName = projectFile;
                return true;
            }

            return false;
        }

        public bool SaveProjectToXML(string projectFile)
        {
            if (XMLModel.SaveProject(projectFile, _deviceModels, _deviceGraphModels))
            {
                this.CurrentXMLFileName = projectFile;
                return true;
            }
            
            return false;
        }

        public bool LoadProjectFromSQL(string projectFile)
        {
            if (SQLModel.LoadProject(_dataContext, _deviceModels, _deviceGraphModels))
            {
                this.CurrentSQLFileName = projectFile;
                return true;
            }

            return false;
        }

        public bool SaveProjectToSQL(string projectFile)
        {
            if (SQLModel.SaveProject(_dataContext, _deviceModels, _deviceGraphModels))
            {
                this.CurrentSQLFileName = projectFile;
                return true;
            }

            return false;
        }

        public List<DeviceBaseModel> GetDeviceModels()
        {
            return new List<DeviceBaseModel>(_deviceModels);
        }

        public List<DeviceBaseGraphModel> GetDeviceGraphModels()
        {
            return new List<DeviceBaseGraphModel>(_deviceGraphModels);
        }

        public void Add(DeviceBaseModel deviceModel)
        {
            if (!_deviceModels.Contains(deviceModel))
            {
                _deviceModels.Add(deviceModel);
            }
        }

        public bool Contains(DeviceBaseModel deviceModel)
        {
            return _deviceModels.Contains(deviceModel);
        }

        public void Remove(DeviceBaseModel deviceModel)
        {
            _deviceModels.Remove(deviceModel);
            if (this.DeviceModelRemoveHandler != null)
            {
                this.DeviceModelRemoveHandler(this, new DeviceModelEventArgs(deviceModel));
            }
        }

        public void Add(DeviceBaseGraphModel deviceGraphModel)
        {
            if (!_deviceGraphModels.Contains(deviceGraphModel))
            {
                _deviceGraphModels.Add(deviceGraphModel);
            }
        }

        public bool Contains(DeviceBaseGraphModel deviceGraphModel)
        {
            return _deviceGraphModels.Contains(deviceGraphModel);
        }

        public void Remove(DeviceBaseGraphModel deviceGraphModel)
        {
            _deviceGraphModels.Remove(deviceGraphModel);
        }

        public void Clear()
        {
            _deviceModels.Clear();
            _deviceGraphModels.Clear();

            File.Delete(CurrentSQLFileName);
            _dataContext = new SQLModelDataContext(CurrentSQLFileName);
            _dataContext.CreateDatabase();
        }

        public List<string> GetDeviceMapViewNames()
        {
            return new List<string>(_deviceGraphModels.Select(v => v.GraphType).Distinct());
        }

        #endregion
    }
}
